package MineGod;

import java.util.ArrayList;

import org.newdawn.slick.geom.*;


public class Utils {

	
	public static boolean intersects(Rectangle a, Rectangle b){
		float x1 = a.getMinX();
		float x2 = b.getMinX();
		float y1 = a.getMinY();
		float y2 = b.getMinY();
		float w1 = a.getWidth();
		float w2 = b.getWidth();
		float h1 = a.getHeight();
		float h2 = b.getHeight();
		if (x1 > (x2 - w1) && x1 < (x2 + w2)){ // Correct xish values
			if (y1 > (y2 - h1) && y1 < (y2 + h2)){
				return true;
			} else{
				return false;
			}
		} else{
			return false;
		}
	}
	
	
	public static Block pointToBlock(double x, double y){
		int chunkIndex = (int)(x/Chunk.CHUNK_PIXEL_WIDTH);
		int xIndex = (int)((x%Chunk.CHUNK_PIXEL_WIDTH)/Block.WIDTH);
		int yIndex = (int)(y/Block.WIDTH);
		try{
			try{
				return MineGod.chunks.get(chunkIndex).blocks[xIndex][yIndex];
			} catch (IndexOutOfBoundsException e){
				return null;
			}
		} catch (ArrayIndexOutOfBoundsException e){
			return null;
		}
	}
	
	public static void changeCurrentBlock(Block b, double x, double y){
		int chunkIndex = (int)(x/Chunk.CHUNK_PIXEL_WIDTH);
		int xIndex = (int)((x%Chunk.CHUNK_PIXEL_WIDTH)/Block.WIDTH);
		int yIndex = (int)(y/Block.WIDTH);
		try{
			MineGod.chunks.get(chunkIndex).blocks[xIndex][yIndex] = b;
		} catch (ArrayIndexOutOfBoundsException e){
		}
	}
	
	
	public static ArrayList<BlockMask> getBlockRing(double x, double y, int radius){
		ArrayList<BlockMask> blocks = new ArrayList<BlockMask>();
		for(int i = -radius; i <= radius; i++){
			for(int j = -radius; j <= radius; j++){
				if((i == -radius || i == radius) || (j == -radius || j == radius)){
					Block b = pointToBlock(x+i*Block.WIDTH, y+j*Block.WIDTH);
					if(b != null){
						blocks.add(new BlockMask(b, x+i*Block.WIDTH, y+j*Block.WIDTH));
					}
				}
			}
		}
		
		return blocks;
	}
	
	
	
	
	public static void changeToAirBlock(double x, double y, Block b){
		int chunkIndex = (int)(x/Chunk.CHUNK_PIXEL_WIDTH);
		int xIndex = (int)((x%Chunk.CHUNK_PIXEL_WIDTH)/Block.WIDTH);
		int yIndex = (int)(y/Block.WIDTH);
		try{
					if (!(yIndex<0) && !(yIndex>=Chunk.CHUNK_HEIGHT) && MineGod.chunks.get(chunkIndex).blocks[(xIndex+Chunk.CHUNK_WIDTH)%Chunk.CHUNK_WIDTH][yIndex].equals(b)){
						//Drop Item
						Entity e = b.dropItem(x, y);
						if (e!=null){
							addEntity(e);
						}
						MineGod.chunks.get(chunkIndex).blocks[(xIndex+Chunk.CHUNK_WIDTH)%Chunk.CHUNK_WIDTH][yIndex] = new BlockAir();
						//Check blocks directly above to see if they need to move
						int n = -1;
						while (!(yIndex+n<0) && MineGod.chunks.get(chunkIndex).blocks[(xIndex+Chunk.CHUNK_WIDTH)%Chunk.CHUNK_WIDTH][yIndex+n].obeyGravity){
							Block b2 = MineGod.chunks.get(chunkIndex).blocks[(xIndex+Chunk.CHUNK_WIDTH)%Chunk.CHUNK_WIDTH][yIndex+n];
							BlockType type = b2.type;
							double dur = b2.durability;
							MineGod.chunks.get(chunkIndex).blocks[(xIndex+Chunk.CHUNK_WIDTH)%Chunk.CHUNK_WIDTH][yIndex+n] = new BlockAir();
							//spawn entity for specific block at x,y+n
							Entity e2 = spawnEntity(x,y+16*n,type,dur);
							if (e2!=null){
								addEntity(e2);
							}
							if (type == BlockType.water  || type == BlockType.lava){
								n = yIndex*-1;
							}
							n--;
						}
						//Check left and right of liquid blocks
						chunkIndex = (int)((x+Block.WIDTH)/Chunk.CHUNK_PIXEL_WIDTH);
						Block b2 = MineGod.chunks.get(chunkIndex).blocks[(xIndex+1+Chunk.CHUNK_WIDTH)%Chunk.CHUNK_WIDTH][yIndex];
						if (b2.isLiquid){
							if(b2.type == BlockType.water){
								spawnHorizontalWater(-1,x,y);
							}else if(b2.type == BlockType.lava){
									spawnHorizontalLava(-1,x,y);
								}
						}
						chunkIndex = (int)((x-Block.WIDTH)/Chunk.CHUNK_PIXEL_WIDTH);
						b2 = MineGod.chunks.get(chunkIndex).blocks[(xIndex-1+Chunk.CHUNK_WIDTH)%Chunk.CHUNK_WIDTH][yIndex];
						if (b2.isLiquid){
							if(b2.type == BlockType.water){
								spawnHorizontalWater(1,x,y);
							}else if (b2.type == BlockType.lava){
								spawnHorizontalLava(1,x,y);
							}
						}
					}
		} catch (ArrayIndexOutOfBoundsException e){
		}
	}
	
	public static Entity spawnEntity(double x, double y, BlockType type, double dur) {
		switch (type){
		case sand:
			return new EntitySand(x,y,dur);
		case water:
			return new EntityWater(0,1,x,y,dur);
		case lava:
			return new EntityLava(0,1,x,y,dur);
		default:
			return null;
		}
	}

	public static void delayAddEntity(Entity e){
		MineGod.delayedEntities.add(e);
	}

	public static void addEntity(Entity e){
		MineGod.entities.add(e);
	}
	
	public static void spawnHorizontalWater(int dir, double x, double y){
		MineGod.entities.add(new EntityWater(dir,0,x,y,1));
	}
	
	public static void spawnHorizontalLava(int dir, double x, double y){
		MineGod.entities.add(new EntityLava(dir,0,x,y,1));
	}
	
	
	public static double convertChunkX(double x, int worldPosIndex){
		return worldPosIndex*Chunk.CHUNK_PIXEL_WIDTH + x;
	}
	
	public static Player getPlayer(){
		return MineGod.player;
	}
	
	
	
	
}
